Skip to content

fix(constructs): emit numeric gRPC health-check status from healthCheckStatus() (SIM-307)#1406

Merged
sorccu merged 1 commit into
mainfrom
daniel/sim-307-grpc-healthcheck-status-label
Jul 17, 2026
Merged

fix(constructs): emit numeric gRPC health-check status from healthCheckStatus() (SIM-307)#1406
sorccu merged 1 commit into
mainfrom
daniel/sim-307-grpc-healthcheck-status-label

Conversation

@danielpaulus

Copy link
Copy Markdown
Contributor

What & why

Fixes SIM-307. GrpcAssertionBuilder.healthCheckStatus() returned a GeneralAssertionBuilder (free string target), so the CLI's own documented example healthCheckStatus().equals('SERVING') shipped target: "SERVING" to the API. The go-runner evaluates gRPC health status numerically (strconv.Atoi(target)), so "SERVING" returns "Invalid. Target health status is not a number" — the advertised example built a permanently-failing check. Only the webapp normalized the label→number; the CLI/raw-API path shipped a broken check.

Root cause: healthCheckStatus() used a string builder while the sibling statusCode() correctly uses NumericAssertionBuilder.

Changes

  • healthCheckStatus() now returns a dedicated HealthCheckStatusAssertionBuilder exposing only .equals()/.notEquals() (the only comparisons the runner supports for health status), accepting a GrpcHealthStatus label or the raw 0|1|2|3 enum and emitting the numeric wire target. The label→number map (UNKNOWN:0, SERVING:1, NOT_SERVING:2, SERVICE_UNKNOWN:3) mirrors the webapp's grpcHealthStatusTargetByLabel — single source of truth, reused by codegen + validation. The documented .equals('SERVING') example now works and matches what's stored (no IaC drift).
  • Codegen reverse-maps the number→label so an imported check with target:'1' round-trips to healthCheckStatus().equals('SERVING'); unmappable/legacy targets fall back to a raw assertion object literal so generated code always type-checks.
  • Validation flags a GRPC_HEALTHCHECK_STATUS target that isn't 0–3, catching object-literal callers who bypass the builder.

Testing

21 gRPC unit + codegen tests green (all four labels → 0–3, .notEquals, raw-number incl. the falsy 0, codegen round-trip for EQUALS/NOT_EQUALS + object-literal fallback, validation positive/negative). tsc --build clean, lint clean.

Review

Reviewed via a tri-model daniel-review (Codex + Gemini + Claude) — no blockers; the confirmed should-fixes (codegen fallback must emit compilable TS; preserve invalid JS-caller value in the diagnostic) were fixed and re-verified before this PR.

Note

The backend counterpart (rejecting a non-numeric health-status target at the API edge) is monorepo #3044 (SIM-306). This PR fixes the CLI/construct side so the friendly label API works end-to-end.

🤖 Generated with Claude Code

…ckStatus() (SIM-307)

GrpcAssertionBuilder.healthCheckStatus() returned a GeneralAssertionBuilder,
so the CLI's own documented example .equals('SERVING') shipped target
"SERVING" to the API. The go-runner evaluates gRPC health status numerically
(strconv.Atoi), so the label could never pass ("Invalid. Target health status
is not a number") — the advertised example built a permanently-failing check.
Only the webapp normalized the label to a number.

- healthCheckStatus() now returns a dedicated HealthCheckStatusAssertionBuilder
  exposing only .equals()/.notEquals() (the only comparisons the runner
  supports), accepting a GrpcHealthStatus label or the raw 0|1|2|3 enum and
  emitting the numeric wire target. Mirrors the webapp's
  grpcHealthStatusTargetByLabel mapping (single source of truth).
- Codegen reverse-maps the number back to the label so an imported check
  round-trips to .equals('SERVING'); unmappable/legacy targets fall back to a
  raw assertion object literal so the generated code always type-checks.
- Validation flags a GRPC_HEALTHCHECK_STATUS target that isn't 0-3, catching
  object-literal callers who bypass the builder.

Reviewed via tri-model daniel-review (Codex + Gemini + Claude); all findings
fixed. Build clean, 21 gRPC unit/codegen tests green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013AYwkvoaANQTH5dGStbBj2
@sorccu
sorccu force-pushed the daniel/sim-307-grpc-healthcheck-status-label branch from de217d3 to 39a3e3b Compare July 17, 2026 18:12
@sorccu
sorccu merged commit 14d5b2d into main Jul 17, 2026
26 of 28 checks passed
@sorccu
sorccu deleted the daniel/sim-307-grpc-healthcheck-status-label branch July 17, 2026 18:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants